package com.ayf.payment.game.api.service.payment;

import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.channel.jiabei.util.HttpHelper;
import com.ayf.payment.game.api.channel.jiabei.util.JbStringUtil;
import com.ayf.payment.game.api.channel.jiabei.util.StringHelper;
import com.ayf.payment.game.api.dto.OrderAndMerchantDTO;
import com.ayf.payment.game.api.dto.platform.MerchantPaymentProductDTO;
import com.ayf.payment.game.api.dto.platform.PaymentChannelDTO;
import com.ayf.payment.game.api.entity.Order;
import com.ayf.payment.game.api.entity.Partition;
import com.ayf.payment.game.api.exception.NullSetException;
import com.ayf.payment.game.api.type.OrderStatus;
import com.ayf.payment.game.api.utils.DateUtils;
import com.ayf.payment.game.api.utils.JsonUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author wwl
 * @description:
 * @date 2020/5/11 17:35
 */
@Service
public class JBPaymentService extends IPaymentService {

    @Override
    public Map<String, Object> paymentUtil(Order order, Partition partition, String orderCreateStr, String traceId, String redirectUrl) {
        Map<String, Object> result = new HashMap<>(3);
        MerchantPaymentProductDTO merchantPaymentProductDTO = systemInitialization.productDTO(order.getPayTypeId());
        PaymentChannelDTO paymentChannelDTO = systemInitialization.channelDTO(merchantPaymentProductDTO.getcId());
        BigDecimal actualOrderAmt = getActualOrderAmt(order.getAmount(),paymentChannelDTO.getId(),partition.getMerchantId());
        String resultCode = orderCreate(order, orderCreateStr, traceId,redirectUrl,actualOrderAmt,merchantPaymentProductDTO,paymentChannelDTO);
        if (resultCode == null) {
            throw new NullSetException("下单失败，请稍后重试！");
        }
        if (resultCode.indexOf("支付跳转") > 0) {
            order.setRandomAmt(BigDecimal.ZERO);
            order.setOrderNo("");
            order.setPayChannleName(paymentChannelDTO.getName());
            order.setPayChannleId(paymentChannelDTO.getId());
            order.setPayTypeId(merchantPaymentProductDTO.getProductId());
            order.setPayTypeName(merchantPaymentProductDTO.getProductName());
            order.setMerchantIncome(BigDecimal.ZERO);
            order.setPlatformIncome(BigDecimal.ZERO);
            order.setFee(BigDecimal.ZERO);
            order.setChannelIncome(BigDecimal.ZERO);
            orderMapper.insertSelective(order);
            result.put("code", "002");
            result.put("htmlMsg", resultCode);
        } else {
            LogPortal.error("PAYMENT_PROGRAM_CHANNEL_ORDER_CREATE_FAIL 嘉贝{} 商户ID[{}] 商户订单号[{}] 支付程序向支付渠道下单失败，响应报文:{}", traceId, partition.getMerchantId(), order.getOrderNo(), resultCode);
            JSONObject jsData = JSONObject.parseObject(resultCode);
            String message = jsData.getString("Message");
            message = StringUtils.isEmpty(message)?"请稍后重试":message;
            throw new NullSetException("充值失败，".concat(message));
        }
        return result;
    }

    @Override
    public void queryPayOrder(OrderAndMerchantDTO dto, String traceId) {
        String orderCreateStr = DateUtils.dateToString(new Date(), DateUtils.formatPattern_full_01);
        PaymentChannelDTO paymentChannelDTO = systemInitialization.channelDTO(dto.getPayChannleId());
        //商户编号
        String MerhantId = paymentChannelDTO.getAccountNumber();
        //测试商户密钥
        String KeyValue = paymentChannelDTO.getChannelKey();
        LogPortal.error("嘉贝{} 执行查询订单商户订单号{}", traceId, dto.getMerchantOrderNo());

        String resultCode = queryCreate(dto.getMerchantId(), dto.getMerchantOrderNo(), traceId, orderCreateStr,paymentChannelDTO);
        LogPortal.error("嘉贝{} 执行查询订单商户订单号{}，执行查询返回结果{}", traceId, dto.getMerchantOrderNo(),resultCode);
        if (resultCode == null) {
            LogPortal.error("嘉贝{} 订单号[{}] 在支付平台查询不到", traceId, dto.getMerchantOrderNo());
            return;
        }
        Map<String, String> map = JsonUtils.fromJson(resultCode, Map.class);
        //获取参数
        String Amount = JbStringUtil.formatString(map.get("Amount"));        //金额 该笔订单的资金总额，单位为RMB。取值范围为[1,10000000.00]。
        String ApiMethod = "QueryPayOrder";                                         // 业务标识 固定值:OnLinePay
        String Ext1 = JbStringUtil.formatString(map.get("Ext1"));          //商户扩展信息 交易请求时上传，通知原样返回
        String OrderNum = JbStringUtil.formatString(map.get("OrderNum"));      // 系统订单号 【支付平台】订单号
        String PayType = JbStringUtil.formatString(map.get("PayType"));       // 支付方式
        String RespCode = JbStringUtil.formatString(map.get("RespCode"));      // 响应代码 请求处理状态1111：处理成功 2222：处理失败
        String ResultCode = JbStringUtil.formatString(map.get("ResultCode"));    //业务处理代码 固定值：101
        String SignType = JbStringUtil.formatString(map.get("SignType"));      // 签名方式
        String Status = JbStringUtil.formatString(map.get("Status"));        // 状态码 订单支付状态: 01:支付成功 02：待支付
        String TradeNum = JbStringUtil.formatString(map.get("TradeNum"));      // 商户订单号 您的网站订单号
        String Version = "V2.0";                                              // 版本号 固定值:V2.0
        String Sign = JbStringUtil.formatString(map.get("Sign"));          // 签名数据
        if (StringUtils.isEmpty(TradeNum)) {
            LogPortal.error("嘉贝{} 支付平台查询订单商户订单号{}数值为空，不进行后续操作", traceId, dto.getMerchantOrderNo());
            return;
        }
        if (TradeNum.equals(dto.getMerchantOrderNo())) {
            LogPortal.error("嘉贝{} 支付平台查询订单返回商户订单号不批配，不进行后续操作", traceId, dto.getMerchantOrderNo());
            return;
        }
        Order order = orderService.selectByMerchantOrderNo(TradeNum);
        if (order == null) {
            LogPortal.error("嘉贝{} 订单号[{}]在我方系统查询不到", traceId, TradeNum);
            return;
        }
        //生成签名
        HashMap<String, String> dicMap = new HashMap<String, String>();
        dicMap.put("Amount", Amount);
        dicMap.put("ApiMethod", ApiMethod);
        dicMap.put("Ext1", Ext1);
        dicMap.put("MerID", MerhantId);
        dicMap.put("OrderNum", OrderNum);
        dicMap.put("PayType", PayType);
        dicMap.put("RespCode", RespCode);
        dicMap.put("ResultCode", ResultCode);
        dicMap.put("SignType", SignType);
        dicMap.put("Status", Status);
        dicMap.put("TradeNum", TradeNum);
        dicMap.put("Version", Version);
        SortedMap<String, String> sortMap = new TreeMap<String, String>(dicMap);
        String signData = StringHelper.createSign(sortMap);
        String signVer = StringHelper.EncodeMD5(signData + "key=" + KeyValue);
        LogPortal.info("嘉贝{} 接收到查询支付平台订单返回内容为：{} signVER: {}", traceId, signData, signVer);
        if (Sign.trim().equals(signVer.trim())) {
            if ("01".equals(Status)) {
                if (OrderStatus.PROCESSING.equals(order.getOrderStatus())) {
                    order.setOrderNo(OrderNum);
                    order.setOrderStatus(OrderStatus.SUCCESS);
                    orderService.paymentOrder(order, new JSONObject());
                    if (OrderStatus.SUCCESS.equals(order.getOrderStatus())) {
                        orderService.orderToGetWay(order);
                        wxSendMsgUtils.rechargeSuccess(order);
                    }
                }
            } else {
                LogPortal.error("嘉贝{} 商户订单号[{}] 异步通知验签失败", traceId, TradeNum);
            }
        } else {
            LogPortal.error("嘉贝{} 商户订单号[{}] 异步通知验签失败", traceId, TradeNum);
        }
    }


    private String queryCreate(Integer merId, String TradeNum, String traceId, String TransTime,PaymentChannelDTO paymentChannelDTO) {
        traceId = "嘉贝订单查询 ".concat(traceId);
        //商户编号
        String MerhantId = paymentChannelDTO.getAccountNumber();
//        //测试商户密钥
        String KeyValue = paymentChannelDTO.getChannelKey();
//        //交易请求地址
        String AuthorizationURL = paymentChannelDTO.getPaymentUrl();
        HashMap<String, String> dicMap = new HashMap<String, String>();
        dicMap.put("ApiMethod", "QueryPayOrder");//业务标识 固定值:QueryPayOrder
        dicMap.put("Version", "V2.0");//版本号 固定值:V2.0
        dicMap.put("MerID", MerhantId);//商户号 商户号
        dicMap.put("TradeNum", TradeNum);
        dicMap.put("TransTime", TransTime);
        dicMap.put("SignType", "MD5");

        SortedMap<String, String> SortMap = new TreeMap<String, String>(dicMap);

        String signData = StringHelper.createSign(SortMap);
        //生成签名
        String sign = StringHelper.EncodeMD5(signData + "key=" + KeyValue);

        dicMap.put("Sign", sign);

        SortedMap<String, String> SortParamMap = new TreeMap<String, String>(dicMap);
        //生成请求字符串
        String param = StringHelper.createSign(SortParamMap);
        String result = "";
        try {
            //请求上游接口
            result = HttpHelper.sendPost(AuthorizationURL, param.substring(0, param.length() - 1), traceId);

        } catch (Exception e) {
            //  LogPortal.error("嘉贝{} PAYMENT_PROGRAM_CHANNEL_ORDER_CREATE_FAIL 商户ID[{}] 商户订单号[{}] 支付渠道查询订单失败，发生了{}异常，错误描述:{}", traceId, order.getMerchantId(), order.getMerchantOrderNo(), e.getClass().getName(), e.getMessage());
            LogPortal.error("嘉贝{} 商户ID[{}] 商户订单号[{}] 支付渠道查询订单失败，发生了{}异常，错误描述:{}", e, traceId, merId, TradeNum, e.getClass().getName(), e.getMessage());
        }
        return result;
    }

    private String orderCreate(Order order, String orderCreateStr, String traceId, String redirectUrl,BigDecimal actualOrderAmt,MerchantPaymentProductDTO merchantPaymentProductDTO,PaymentChannelDTO paymentChannelDTO) {
        traceId="嘉贝创建订单 ".concat(traceId);
        //商户编号
        String MerhantId =paymentChannelDTO.getAccountNumber();
        //测试商户密钥
        String KeyValue = paymentChannelDTO.getChannelKey();
        //交易请求地址
        String AuthorizationURL = paymentChannelDTO.getPaymentUrl();

        HashMap<String, String> dicMap = new HashMap<String, String>();
        dicMap.put("ApiMethod", "OnLinePay");
        dicMap.put("Version", "V2.0");
        dicMap.put("MerID", MerhantId);
        dicMap.put("TradeNum", order.getMerchantOrderNo());  //商户订单号
        dicMap.put("Amount",String.valueOf(actualOrderAmt));      // 交易金额 该笔订单的资金总额，单位为：RMB。取值范围为[1，10000000.00]，精确到小数点后两位。
        dicMap.put("GoodsName", "");  // 商品名称 用户购买的商品名称，如参数值有中文需要进行url编码后发送到支付平台
        dicMap.put("GoodsDesc", "");  // 商品描述 用户购买商品的描述信息，如参数值有中文需要进行url编码后发送到支付平台
        dicMap.put("NotifyUrl", paymentChannelDTO.getReturnUrl()+"/gameapip/v/jb/pay/notify");  // 服务器异步通知路径http://test1gameweb2.azbpay.com/gws/paymentSuccess.html#
        dicMap.put("ReturnUrl", "");  // 页面跳转同步通知页面
        dicMap.put("TransTime", orderCreateStr);  //请求时间
        dicMap.put("Ext1", "");            // 商户扩展信息 通知时原样返回，由字母和数字组成 不能超过20大小
        dicMap.put("PayType", getPayCode(merchantPaymentProductDTO.getBusinessCode()));      // 支付方式
        dicMap.put("BankCode", "");    // 银行编码
        dicMap.put("AgeID", "29");
        dicMap.put("SignType", "MD5");   // 签名方式 参数的签名方式，固定值：MD5

        SortedMap<String, String> sortMap = new TreeMap<String, String>(dicMap);
        String signData = StringHelper.createSign(sortMap);
        String sign = StringHelper.EncodeMD5(signData + "key=" + KeyValue);
        dicMap.put("Sign", sign);

        SortedMap<String, String> SortParamMap = new TreeMap<String, String>(dicMap);
        //生成请求字符串
        String param = StringHelper.createSign(SortParamMap);
        LogPortal.info("嘉贝{} 商户ID[{}] 商户订单号[{}] 下单请求参数[{}]", traceId, order.getMerchantId(), order.getMerchantOrderNo(), param);
        String result = "";
        try {
            //请求上游接口
            result = HttpHelper.sendPost(AuthorizationURL, param.substring(0, param.length() - 1), traceId);
            LogPortal.info("嘉贝{} 商户ID[{}] 商户订单号[{}] 调用支付渠道下单接口成功，响应报文:{}", traceId, order.getMerchantId(), order.getMerchantOrderNo(), result);
        } catch (Exception e) {
            LogPortal.error("嘉贝{} PAYMENT_PROGRAM_CHANNEL_ORDER_CREATE_FAIL 商户ID[{}] 商户订单号[{}] 支付程序向支付渠道下单失败，发生了{}异常，错误描述:{}", traceId, order.getMerchantId(), order.getMerchantOrderNo(), e.getClass().getName(), e.getMessage());
            LogPortal.error("嘉贝{} 商户ID[{}] 商户订单号[{}] 支付程序向支付渠道下单失败，发生了{}异常，错误描述:{}", e, traceId, order.getMerchantId(), order.getMerchantOrderNo(), e.getClass().getName(), e.getMessage());
        }
        return result;
    }

    private String getPayCode(String code){
        if("ALIPAY".equals(code)||"ANTCREDITPAY".equals(code)){
            return "alipay";
        } else if("WXCODE".equalsIgnoreCase(code) || "WECHAT".equals(code)){
            return "wxcode";
        } else {
            throw new NullSetException("该通道不支持充值，请更换其他通道充值！");
        }
    }
}
